﻿using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/// <summary>
/// 1.SetVerticesDirty  设置赃顶点的时候，获取到需要的顶点信息
/// 2.OnPopulateMesh   根据需要设置图片的顶点信息，去创建图片
/// </summary>
public class OnlieText : Text ,IPointerClickHandler
{
    /// <summary>
    /// 用正则表达式取标签属性, 名称-大小-宽度比例
    /// </summary>
    private static readonly Regex m_spriteTagRegex =
        new Regex(@"<quad name=(.+?) size=(\d*\.?\d+%?) width=(\d*\.?\d+%?) />",RegexOptions.Singleline);

    /// <summary>
    /// 超链接正则
    /// </summary>
    private static readonly Regex s_HrefRegex =
        new Regex(@"<a href=([^>\n\s]+)>(.*?)(</a>)", RegexOptions.Singleline);

    /// <summary>
    /// 静态图标 预制体列表
    /// </summary>
    private List<ImageObject> m_emojiInfos;

    /// <summary>
    /// 超链接需要的参数
    /// </summary>
    private List<HyperlinkObject> m_linkInfos;

    /// <summary>
    /// 文本构造器
    /// </summary>
    private StringBuilder m_textBuilder = new StringBuilder();

    public override string text
    {
        get
        {
            return base.text;
        }

        set
        {
            ClearEmoji();
            base.text = CreateHyperlink(value);
            CreateStaticImg();
        }
    }

    /// <summary>
    /// 在设置顶点时调用
    /// </summary>
    public override void SetVerticesDirty()
    {
        base.SetVerticesDirty();
    }

    /// <summary>
    /// 绘制模型，文字的顶点排列顺序  0   1 
    ///                               3   2  从左上角顺时针排列
    /// </summary>
    /// <param name="toFill"></param>
    protected override void OnPopulateMesh(VertexHelper toFill)
    {
        base.OnPopulateMesh(toFill);

        //设置静态表情
        if (m_emojiInfos != null)
        {
            List<UIVertex> listUIVertex = new List<UIVertex>();
            toFill.GetUIVertexStream(listUIVertex);

            for (int i = 0; i < m_emojiInfos.Count; i++)
            {
                //quad 会出现乱码现象，把quad的uv设置成0，去除乱码
                int vertexIndex = m_emojiInfos[i].Index * 6;
                for (int index = vertexIndex; index < vertexIndex + 6; index++)
                {
                    UIVertex tempVertex = listUIVertex[index];
                    tempVertex.uv0 = Vector2.zero;
                    listUIVertex[index] = tempVertex;
                }

                //设置图片的位置
                m_emojiInfos[i].transform.localPosition = listUIVertex[vertexIndex + 4].position;
            }

            //清除 < quad /> 标签的乱码 重新绘制
            toFill.Clear();
            toFill.AddUIVertexTriangleStream(listUIVertex);
        }

        //设置超链接
        if (m_linkInfos != null)
        {
            List<UIVertex> listUIVertex = new List<UIVertex>();
            toFill.GetUIVertexStream(listUIVertex);

            //处理超链接包围框
            foreach (var hrefInfo in m_linkInfos)
            {
                hrefInfo.boxes.Clear();
                if (hrefInfo.startIndex >= listUIVertex.Count)
                {
                    continue;
                }

                //将超链接里面的文本顶点索引坐标加入到包围框
                UIVertex vertex = listUIVertex[hrefInfo.startIndex];
                Bounds bounds = new Bounds(vertex.position, Vector3.zero);
                for (int i = hrefInfo.startIndex, m = hrefInfo.endIndex; i < m; i++)
                {
                    if (i >= listUIVertex.Count)
                    {
                        break;
                    }

                    vertex = listUIVertex[i];
                    if (vertex.position.x < bounds.min.x)  // 换行重新添加包围框
                    {
                        hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size));
                        bounds = new Bounds(vertex.position, Vector3.zero);
                    }
                    else
                    {
                        bounds.Encapsulate(vertex.position);  // 扩展包围框
                    }
                }
                hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size));
            }
        }

    }

    /// <summary>
    /// 生成静态表情
    /// </summary>
    private void CreateStaticImg()
    {
        ImageObject imageInfo;
        foreach (Match match in m_spriteTagRegex.Matches(text))
        {
            imageInfo = ImgTxtObjectPoolMgr<ImageObject>.Spawn(ImgTxtType.staticEmoji);

            imageInfo.Index = match.Index;
            imageInfo.Name = match.Groups[1].Value;
            imageInfo.transform.SetParent(transform);
            imageInfo.Size = new Vector2(float.Parse(match.Groups[2].Value) * float.Parse(match.Groups[3].Value), float.Parse(match.Groups[2].Value));

            if (m_emojiInfos == null)
                m_emojiInfos = new List<ImageObject>();
            m_emojiInfos.Add(imageInfo);
        }
    }

    /// <summary>
    /// 生成超链接
    /// </summary>
    /// <returns></returns>
    private string CreateHyperlink(string strValue)
    {
        m_textBuilder.Length = 0;
        //截取字符串 索引
        int indexText = 0;

        HyperlinkObject linkInfo;
        foreach (Match match in s_HrefRegex.Matches(strValue))
        {
            //拼接文本
            m_textBuilder.Append(strValue.Substring(indexText, match.Index - indexText));

            //赋值信息
            linkInfo = ImgTxtObjectPoolMgr<HyperlinkObject>.Spawn(ImgTxtType.hyperlink);
            linkInfo.strInfo = match.Groups[1].Value;
            linkInfo.startIndex = m_textBuilder.Length * 6;  // 超链接里的文本起始顶点索引
            linkInfo.endIndex = (m_textBuilder.Length + match.Groups[2].Length - 1) * 6 + 3;

            if (m_linkInfos == null)
                m_linkInfos = new List<HyperlinkObject>();
            m_linkInfos.Add(linkInfo);
            
            m_textBuilder.Append(match.Groups[2].Value);
            //计算新的位置
            indexText = match.Index + match.Length;
        }

        return m_textBuilder.Length  == 0 ? strValue : m_textBuilder.ToString();
    }

    /// <summary>
    /// 清除当前的图文混排
    /// </summary>
    private void ClearEmoji()
    {
        if (m_emojiInfos != null)
        {
            for (int i = 0; i < m_emojiInfos.Count; i++)
            {
                ImgTxtObjectPoolMgr<ImageObject>.Recycle(m_emojiInfos[i]);
            }
            m_emojiInfos.Clear();
        }

        if (m_linkInfos != null)
        {
            for (int i = 0; i < m_linkInfos.Count; i++)
            {
                ImgTxtObjectPoolMgr<HyperlinkObject>.Recycle(m_linkInfos[i]);
            }
            m_linkInfos.Clear();
        }
    }

    /// <summary>
    /// 超链接点击 事件
    /// </summary>
    /// <param name="eventData"></param>
    public void OnPointerClick(PointerEventData eventData)
    {
        if (m_linkInfos == null || m_linkInfos.Count == 0) return;

        Vector2 lp;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
        rectTransform, eventData.position, eventData.pressEventCamera, out lp);

        HyperlinkObject linkObject = null;
        for (int index = 0;index < m_linkInfos.Count; index++)
        {
            linkObject = m_linkInfos[index];

            if (linkObject.boxes == null || linkObject.boxes.Count == 0) continue;

            for (var i = 0; i < linkObject.boxes.Count; ++i)
            {
                if (linkObject.boxes[i].Contains(lp))
                {
                    //m_OnHrefClick.Invoke(hrefInfo.name);
                    Debug.LogError("触发超链接点击事件:" + linkObject.name);
                    return;
                }
            }
        }
    }

    protected override void OnDestroy()
    {
        ClearEmoji();
    }
}
